/**
 * 带错误原始数据的错误类型
 */
export class GError<T> extends Error
{
    /**
     * 操作哪个原始数据才出错的
     */
    errorSource?: T

    /**
     * 什么操作导致的错误
     */
    operaDetail?: string
}

/**
 * 把一个基本类型错误封装成GError
 * @param error 
 * @param errorSource 
 * @returns 
 */
export function GErrorWrapWithSource<T extends GError<any>>(error: T, errorSource: any, operaDetail?: string): T
export function GErrorWrapWithSource<T extends GError<any>>(error: Error, errorSource: any, operaDetail?: string): T
export function GErrorWrapWithSource<T>(error: Error, errorSource: T, operaDetail?: string): GError<T>
export function GErrorWrapWithSource(error: Error, errorSource: any, operaDetail?: string)
{
    let gErr = new GError()
    if(error instanceof GError) {gErr = error}
    gErr.errorSource = errorSource
    gErr.message = error.message
    gErr.name = error.name
    gErr.stack = error.stack
    gErr.operaDetail = operaDetail
    return gErr
}

/**
 * 进行某个函数操作，报错时封装成GError
 * @param func 函数本体
 * @param errorSource 被操作的东西
 * @param operaDetail 描述进行了什么操作
 * @returns 
 */
export function GErrorDo<T,KT>(func: () => T, errorSource: KT, operaDetail?:string): T
{
    try
    {
        return func()
    }
    catch(xErr)
    {
        let err = xErr as Error
        throw GErrorWrapWithSource(err, errorSource, operaDetail)
    }
}

/**
 * 判断一个东西是不是GError
 * @param x 
 */
export function isGError<T extends GError<any>>(x: any): x is T
export function isGError<T>(x: any): x is GError<T>
export function isGError(x: any)
{
    return x instanceof GError
}